#计算函数的梯度
import numpy as np

#定义二元函数y=x0*x0+x1*x1
def function_2(x):
    return x[0]**2 + x[1]**2

#定义梯度函数
def numerical_gradient(f, x):
    h = 1e-4  #0.0001
    #生成一个与x形状相同、所有元素均为0的数组
    grad = np.zeros_like(x)

    for idx in range(x.size):
        tmp_val = x[idx]
        #计算f(x+h)
        x[idx] = tmp_val + h
        fxh1 = f(x)

        #计算f(x-h)
        x[idx] = tmp_val - h
        fxh2 = f(x)

        grad[idx] = (fxh1 - fxh2) / (2.0*h)
        #还原值
        x[idx] = tmp_val

    return grad

z1 = numerical_gradient(function_2, np.array([3.0, 4.0]))
print('在[3.0, 4.0]处的梯度为：' + str(z1))
z2 = numerical_gradient(function_2, np.array([0.0, 2.0]))
print('在[0.0, 2.0]处的梯度为：' + str(z2))
z3 = numerical_gradient(function_2, np.array([3.0, 0.0]))
print('在[3.0, 0.0]处的梯度为：' + str(z3))
